home *** CD-ROM | disk | FTP | other *** search
/ ADA Programming Guide / ADA Programming Guide.iso / ada_gwu / machine.c < prev    next >
C/C++ Source or Header  |  1996-01-30  |  4KB  |  180 lines

  1. /*
  2.  * Copyright (C) 1985-1992  New York University
  3.  * 
  4.  * This file is part of the Ada/Ed-C system.  See the Ada/Ed README file for
  5.  * warranty (none) and distribution info and also the GNU General Public
  6.  * License for more details.
  7.  
  8.  */
  9.  
  10. /* machine.c - procedures which optionally may be recoded in assembly language
  11.  * 
  12.  * This file contains procedures which perform the integer arithmetic 
  13.  * operations (addition, subtraction and multiplication) which require 
  14.  * overflow detection of the result. C does not provide an efficient 
  15.  * mechanism for catching overflows, so this is accomplished by doing 
  16.  * some checking of the signs of the operands and result. 
  17.  * 
  18.  * A more appropriate mechanism, would be to have this computation and 
  19.  * overflow check written in assembly language, where more control of 
  20.  * the overflow bit can be realized.
  21.  *
  22.  * Each of the arithmetic procedures accept three parameters. The first 
  23.  * two are the operands and the third is a pointer to an int representating
  24.  * a flag indicating whether there was an overflow in the operation or not.
  25.  *
  26.  * All of the arithmetic procedures can be compiled as is, however 
  27.  * if there is a desire for an more efficient implementation assembly 
  28.  * routine can be supplied which will supercede the C versions. If 
  29.  * this is done you must define the appropriate symbolic name immediately 
  30.  * below to avoid compiling the c prototype code. For example, once 
  31.  * word_add is done in assembly, insert a define for WORD_ADD under 
  32.  * an "ifdef" for the appropriate machine (sun, vax, etc) as is shown 
  33.  * for the IBM_PC case below.
  34.  * 
  35.  * MOVE_MEM is included here only because some run-time libraries might
  36.  * contain a routine which does the equivalent job and therefore could
  37.  * be substituted for the C code given here for it.
  38.  */
  39.  
  40. #include "config.h"
  41. #include "machinep.h"
  42.  
  43. /*
  44.  * macros used to check for overflow condition on integer addition and 
  45.  * subtraction. We assume twos complement arithmetic with wraparound on 
  46.  * overflow 
  47.  */
  48.  
  49. #define sign(x) (x < 0 ? 1 : 0)
  50. #define addoverflow(op1,op2,res) (sign(op1)==sign(op2) && sign(res)!=sign(op1))
  51. #define suboverflow(op1,op2,res) (sign(op1)!=sign(op2) && sign(res)!=sign(op1))
  52.  
  53. #ifndef WORD_ADD
  54. int word_add(int a, int b, int *overflow)                        /*;word_add*/
  55. {
  56.     /* add with overflow check */
  57.  
  58.     register int r;
  59.  
  60.     r = a + b;
  61.     *overflow = addoverflow(a, b, r);
  62.     return r;
  63. }
  64. #endif
  65.  
  66. #ifndef WORD_SUB
  67. int word_sub(int a, int b, int *overflow)                        /*;word_sub*/
  68. {
  69.     /* subtract with overflow check */
  70.  
  71.     register int r;
  72.  
  73.     r = a - b;
  74.     *overflow = suboverflow(a, b, r);
  75.     return r;
  76. }
  77. #endif
  78.  
  79. #ifndef WORD_MUL
  80. int word_mul(int a, int b, int *overflow)                        /*;word_mul*/
  81. {
  82.     /* multiply with overflow check */
  83.  
  84.     register int r;
  85.  
  86.     if(a) {
  87.         r = a * b;
  88.         *overflow = (b != r/a) || (a == -1 && b < 0 && r < 0);
  89.     }
  90.     else {
  91.         *overflow = r = 0;
  92.     }
  93.     return r;
  94. }
  95. #endif
  96.  
  97. #ifndef LONG_ADD
  98. long long_add(long a, long b, int *overflow)                    /*;long_add*/
  99. {
  100.     /* add with overflow check */
  101.  
  102.     register long r;
  103.  
  104.     r = a + b;
  105.     *overflow = addoverflow(a, b, r);
  106.     return r;
  107. }
  108. #endif
  109.  
  110. #ifndef LONG_SUB
  111. long long_sub(long a, long b, int *overflow)            /*;long_sub*/
  112. {
  113.     /* subtract with overflow check */
  114.  
  115.     register long r;
  116.  
  117.     r = a - b;
  118.     *overflow = suboverflow(a, b, r);
  119.     return r;
  120. }
  121. #endif
  122.  
  123. #ifndef LONG_MUL
  124. long long_mul(long a, long b, int *overflow)                    /*;long_mul*/
  125. {
  126.     /* multiply with overflow check */
  127.  
  128.     register long r;
  129.  
  130.     if(a) {
  131.         r = a * b;
  132.         *overflow = (b != r/a) || (a == -1 && b < 0 && r < 0);
  133.     }
  134.     else {
  135.         r = 0;
  136.         *overflow = (int)r;
  137.     }
  138.     return r;
  139. }
  140. #endif
  141.  
  142. #ifndef MOVE_MEM
  143. void move_mem(int *src, int *dst, int n)                    /*;move_mem*/
  144. {
  145.     /* move n words from src to dst
  146.      * We must watch for possible overlap.
  147.      */
  148.  
  149.     unsigned long usrc, udst;
  150.     unsigned int i;
  151.  
  152.     /* View pointers as unsigned to see if possible overlap */
  153.     if (n==0) return;
  154.     usrc = (unsigned) src;
  155.     udst = (unsigned) dst;
  156.     if (usrc >= udst) { /* if no possibility of overlap */
  157.         for (i=0;i<n;i++)
  158.             *dst++ = *src++;
  159.     }
  160.     else {
  161.         /* Here if possible overlap (usrc<udst) , set base to smaller 
  162.          * of pointer values and determine corresponding indices 
  163.          */
  164.         if ((usrc + sizeof(int)*(n-1)) < udst ) { /* can use upwards loops */
  165.             for (i=0; i<n; i++)
  166.                 *dst++ = *src++;
  167.         }
  168.         else { /* overlap, must move backwards */
  169.             ;
  170.             n--;
  171.             dst += n;
  172.             src += n;
  173.             for (i=0; i<=n; i++) {
  174.                 *dst-- = *src--;
  175.             }
  176.         }
  177.     }
  178. }
  179. #endif
  180.